var globalCommunicator = null;
var globalListElement = null;
var globalSelectedItem = null;
var globalButtons = new Array();
var globalCurrentYear = 2012;

/*Primeira função chamada pelo HTML quando é carregado*/
function loadPage(){
    //aqui faz as tarefas antes das solicitações
    makeEarlyTasks();
    
    globalCommunicator = new Communicator();
    requestListDefault();
    globalListElement = document.getElementById('list');
    getDataMenuButtons();
    clearFields();
    
    addGlobalEvents();
    
    //aqui faz as tarefas após as solicitações
    makeLateTasks();
}

function addGlobalEvents(){
    //evento para todos os fields da área de campos editáveis
    var fields = document.getElementById('fields')
    var inputs = fields.getElementsByTagName('INPUT');
    var inputsLength = inputs.length;

    for(var i = 0; i < inputsLength; i++){
        var input = inputs[i];
        if(input.type == 'text'){
            input.addEventListener('focus', textFieldFocused, true);
            input.addEventListener('blur', textFieldBlured, true);
        } 
    }
}

//Verifica se é default ao deixar o campo de texto. Verifica se algum texto foi informado.
function textFieldBlured(event){
    var input = event.target;
    if(input.getAttribute('DATA-DEFAULT') && input.getAttribute('DATA-DEFAULT') == 'default'){
        if(input.value == ''){
            input.className = 'defaultValue';
            input.value = 'Não definido';
        }else{
            input.removeAttribute('DATA-DEFAULT');
        }
    }
}

//Verifica se é default ao entrar no campo de texto.
function textFieldFocused(event){
    var input = event.target;
    if(input.getAttribute('DATA-DEFAULT') && input.getAttribute('DATA-DEFAULT') == 'default'){
        input.value  = '';
        input.className = '';
    }
}

function preloaderAnimation(){
    var shadowedBackground = document.getElementById('shadowed_background');
    var preloader = document.getElementById('preloader');
    
    //troca de invisible para nada e depois põe visible
    shadowedBackground.className = '';
    shadowedBackground.className = 'visible';
    
    preloader.style.left = (shadowedBackground.offsetWidth / 2) - (preloader.offsetWidth / 2) ;
}

/*
    Parametros: Espera receber uma lista de objetos com a propriedade 'name' e 'id', 
    (opcional) uma mensagem padrão para colocar no item padrão do Combo (que terá value = '', 
    então você poderá testar if('elementSelect'.value == '') pra saber se foi escolhido uma opção ou não),
    (opcional) o id do select que você quer substituir, caso ele exista no HTML,
    e (opcional) o id do item que deve estar selecionado por padrão.

    Retorno: A função retorna um elemento HTML do tipo Select. Então se ele não existir no HTML

    Você deve usar document.getElementById('id de um elemento').appendChild(createComboBox(..., ..., ...))
    para adicionar o elemento Combo recém criado no fina de um elemento na página HTML.

    Para pular o parâmetro do meio, envie null. 
*/
function createComboBox(objectList, defaultMessage, currentElementId, selectedId){
    if(!defaultMessage) defaultMessage = 'selecione um item da lista';
    
    var combo = document.createElement('SELECT');
    var defaultOption = document.createElement('OPTION');
    defaultOption.appendChild(document.createTextNode(defaultMessage));
    defaultOption.value = '';
    combo.appendChild(defaultOption);
    
    //for(var i = 0, objectListLen = objectList.length; i < objectListLen; i++){
    for(var chave in objectList){
        
        var object = objectList[chave];
        var option = document.createElement('OPTION');
        option.value = object.id;
        option.appendChild(document.createTextNode(object.nome));
        if(selectedId == object.id) option.selected = true;
        
        combo.appendChild(option);
    }
    
    if(currentElementId){
        var currentElement = document.getElementById(currentElementId);
        combo.id = currentElementId;
        
        currentElement.parentNode.replaceChild(combo, currentElement);
    }

    return combo;
}

function isString(value){
    return typeof(value) == 'string';
}

function selectComboItem(comboEl, itemId){
    if(isString(comboEl)) comboEl = document.getElementById(comboEl);
    var comboElChildren = comboEl.children;
    var comboElChildrenLen = comboElChildren.length;
    
    for(var i = 0; i < comboElChildrenLen; i++){
        var option = comboElChildren[i];
        
        if(option.value == itemId || '0'+option.value == itemId)
            option.selected = true;
    }
}

function resolveNullField(value, field, message){
    if(value == null){
        field.className = 'defaultValue';
        field.setAttribute('DATA-DEFAULT', 'default');
        if(message) value = message;
        else value = 'Ainda não definido';
    }
    
    field.value = value;
}

function addNewItem(){
    newItemTasks();
    clearFields();
    unselectItem();
    focusFirstField();
    globalButtons['delete'].className = 'button disabled';
    globalButtons['save'].className = 'button';
}

/*Pega os botões para não fazermos isso o tempo todo*/
function getDataMenuButtons(){
    globalButtons['new'] = document.getElementById('botao_novo');
    globalButtons['save'] = document.getElementById('botao_salvar');
    globalButtons['delete'] = document.getElementById('botao_deletar');
}

function saveData(){
    if(globalSelectedItem != null) saveEditedItem();
    else saveNewItem();
}


/*
Função genérica de criar as listagens.
Deve-se implementar createElementsObjects em cada caso.
*/
function createList(resposta){
    var respostaObj = eval(resposta);
 
    var fragment = createElementsObjects(respostaObj);
    globalListElement.innerHTML = '';
    globalListElement.appendChild(fragment);
}

function selectItem(event){
    var item = event.target;
    while(item.className != 'list_item') item = item.parentNode;
    
    unselectListItems();
    selectListItems(item);
    
    var key = item.getAttribute('DATA-KEY');
    var object = getSelectedObject(key);
    globalSelectedItem = object;
    
    fillFields(object);
   
    globalButtons['save'].className = 'button';
    globalButtons['delete'].className = 'button';
}

function selectListItems(el){
    el.className = 'list_item selected';
}

function doChangeHandler(resposta){ 
    var respostaObj = eval(resposta);
    if(respostaObj && respostaObj[0] == 'error'){
        alert(respostaObj[1]);
    }else{
        requestListDefault();
    }
}

function receiveResponse(resposta){
}

function clearFields(){
    var fields = document.getElementById('fields');
    var fieldsInputs = fields.getElementsByTagName('INPUT');
    var fieldsInputsLen = fieldsInputs.length;
    
    var fieldsSelects = fields.getElementsByTagName('SELECT');
    var fieldsSelectsLen = fieldsSelects.length;
    
    //se for texto, esvazia. se for checkbox, desmarca...
    for(var i = 0; i < fieldsInputsLen; i++){
        var input = fieldsInputs[i];
        if(input.type == 'checkbox') input.checked = false;
        else if(input.type == 'text'){
            input.value = '';
            input.removeAttribute('DATA-DEFAULT');
        } 
    }
    
    //limpa os Selects, retorna para os values 0, default
    for(var i = 0; i < fieldsSelectsLen; i++){
        var selectChildren = fieldsSelects[i].children;
        var selectChildrenLen = selectChildren.length;
        
        for(var ii = 0; ii < selectChildrenLen; ii++){
            var option = selectChildren[ii];
            if(option.value == 0){
                option.selected = true;
                break;
            } 
        }
    }
    
    //Limpa relatedBox lists. Implementar esta função vazia no script local caso nao hajam related boxes
    clearSpecificElements();
}

function unselectListItems(){
    var listItens = globalListElement.children;
    var listItensLen = listItens.length;
    
    for(var i = 0; i < listItensLen; i++){
        listItens[i].className = 'list_item';
    }
}

function unselectItem(){
    unselectListItems();
    globalSelectedItem = null;
}

function convertDateTimeCorrectFormat(datetime){
    var datetimeParts = datetime.split(' ');
    var date = datetimeParts[0];
    var time = datetimeParts[1];
    
    var dateParts = date.split('-');
    
    return {date: dateParts[2]+'/'+dateParts[1]+'/'+dateParts[0] , time: time}
}

function addItemRelatedBox(relatedBox, type){
    //if(isString(relatedBox)) relatedBox = document.getElementById(relatedBox);
    var item = createRelatedBoxTypeItem(type);
    
    var relatedBoxList = relatedBox.getElementsByClassName('list')[0];
    relatedBoxList.appendChild(item);
}

function clearRelatedBoxList(relatedBox){
    if(isString(relatedBox)) relatedBox = document.getElementById(relatedBox);
    var list = relatedBox.getElementsByClassName('list')[0];
    list.innerHTML = '';
}

function filterJogadoresByClube(id){
    if(isString(id)) id = [id];
    
    var jogadores = globalJogadores;
    var filterJogadores = new Array();
    var idLen = id.length;
    
    for(var key in jogadores){
        var jogador = jogadores[key];
        for(var i = 0; i < idLen; i++){
            if(jogador.clube == id[i]) filterJogadores[key] = jogador;
        }
    }
    
    return filterJogadores;
}

function filterClubesById(id){
    if(isString(id)) id = [id];
    var clubes = globalClubes;
    var filterClubes = new Array();
    var idLen = id.length;
    
    for(var key in clubes){
        var clube = clubes[key];
        for(var i = 0; i < idLen; i++){
            if(clube.id == id[i]) filterClubes[key] = clube;
        }
    }
    
    return filterClubes;
}

function createComboMonths(id, selectId){    
    var months = new Array();
    var monthsNames = ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'];
    
    for(var i = 1; i<=12; i++){
        var indexString = (i < 10) ? '0'+i : i;
        var month = {id: indexString.toString(), nome: monthsNames[i-1]};
        months.push(month);
    }
    
    return createComboBox(months, 'Mês', id, selectId);
}

function createComboDays(id, month, leap, selectId){
    var days = new Array();
    
    var limit = 31;
    if(month && !(month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12)) limit--;
    else if(month == 2){
        limit--;
        if(leap) limit--;
    }
    
    for(var i = 1; i<=limit; i++){
        var indexString = (i < 10) ? '0'+i : i;
        var day = {id: indexString.toString(), nome: indexString.toString()};
        days.push(day);
    }
    
    return createComboBox(days, 'Dia', id, selectId);
}

function createComboHours(id){
    var hours = new Array();
    
    for(var i = 0; i<24; i++){
        var indexString = (i < 10) ? '0'+i : i;
        var hour = {id: indexString.toString(), nome: indexString.toString()};
        hours.push(hour);
    }
    
    return createComboBox(hours, 'Hora', null, id);
}

function createComboMinutes(id){
    var minutes = new Array();
    
    for(var i = 0; i<60; i++){
        var indexString = (i < 10) ? '0'+i : i;
        var minute = {id: indexString.toString(), nome: indexString.toString()};
        minutes.push(minute);
    }
    
    return createComboBox(minutes, 'Minuto', null, id);
}

function isLeapYear(year){
     if(year % 400 == 0) return true;
     else if(year % 100 == 0) return false;
     else if(year % 4 == 0) return true;
     
     return false;
}

function isNumeric(input){
    return input == parseFloat(input);
}

function isStringForm(input){
    return typeof(input)=='string' && isNaN(input);
}

function retrieveCorrectFormat(datetime){
    if(!isString(datetime) || datetime == null) return null;
    else{
        var datetimeParts = datetime.split(' ');
        var date = datetimeParts[0];
        var time = datetimeParts[1];
        
        var day, month, year;
        
        if(date.search('/') != -1){
            date = date.split('/');
            
            day = date[0];
            month = date[1];
            year = date[2];            
        }else{
            date = date.split('-');
            
            day = date[2];
            month = date[1];
            year = date[0];
        }        

        time = time.split(':');
        
        var hour = time[0];
        var minute = time[1];
        
        return day+'/'+month+'/'+year+' '+hour+':'+minute;
    }
}

function validateNullDate(datetime){
    if(!isString(datetime)) return false;
    
    if(datetime != null){
        var datetimeParts = datetime.split(' ');
        var date = datetimeParts[0];
        
        var day, month, year;
        
        if(date.search('/' != -1)){
            date = date.split('/');
            
            day = date[0];
            month = date[1];
            year = date[2];            
        }else{
            date = date.split('-');
            
            day = date[2];
            month = date[1];
            year = date[0];
        }        
        
        if((month == 4 || month == 6 || month == 9 || month == 11) && day > 30) return false
        if(month == 2){
            if(isLeapYear(year)){
                if(day > 28) return false;
            }else{
                if(day > 29) return false;
            }
        }
        
        var time = datetimeParts[1];
        time = time.split(':');
        
        var hora = time[0];
        var minuto = time[1];
        
        if(hora > 23 || hora < 0 || minuto > 59 || minuto < 0) return false;
    }    
    
    return true;
}

function createArrayPastYears(qt, superiorLimit){
    if(!superiorLimit) superiorLimit = 0;
    var yearsArray = new Array();
    
    for(var i = 0; i < qt; i++){
        var mod = superiorLimit + i;
        yearsArray.push({id: globalCurrentYear-mod,  nome: globalCurrentYear-mod});
    }
    
    return yearsArray;
}

//Valida um ano, passando uma string quebrada ou inteira vindo com as barras (/)
function validateDate(day, month, year){
    if(!month && !year){ //verifica se veio string separada por / ou separa em variaveis
        var datetime = day;
        
        if(datetime.search(' ')) datetime = datetime.split(' ')[0];
        
        var datetimeParts = datetime.split('/');
        
        day = datetimeParts[0];
        month = datetimeParts[1];
        year = datetimeParts[2];
    }
      
    
    if((month == 4 || month == 6 || month == 9 || month == 11) && day > 30) return false
    if(month == 2){
        if(isLeapYear(year)){
            if(day > 29) return false;
        }else{
            if(day > 28) return false;
        }
    }
    
    return true;
}

//Transforma no formato do ano, desde que a entrada seja
//dd/mm/aa(aa) ou dd/mm/aa(aa) hh:mm
function retrieveDatetimeDatabaseFormat(datetime){
    if(datetime == null) return null;
    var returnDate, date;
    
    if(datetime.search(' ') != -1){
        var datetimeParts = datetime.split(' ');
        date = datetimeParts[0].split('/');
        returnDate = date[2]+'-'+date[1]+'-'+date[0]+' '+datetimeParts[1];
    }else{
        date = datetimeParts[0].split('/');
        returnDate = date[2]+'-'+date[1]+'-'+date[0];
    }  
    
    return returnDate;
}

function validateAssignFields(communicator, fields, obj){
    if(isString(fields)) fields = [fields]; //Rever
    
    globalValidationFailed = new Array();
    communicator.resetParameters();
    
    var feedback, value, validate;
    var fieldAssigned = false;
    
    for(var field in fields){
        validate = true; 
        value = fields[field];
        feedback = false;

        if(obj && obj[field] == value) validate = false; //Se for igual, não valida        
        if(validate){ 
            //valida os campos
            feedback = validateFields(field, value);
            
            if(feedback == false){//Ocorreu validação com suceso
                //Correções de formato
                if(field == 'hora_planejada' || field == 'hora_realizada') value = retrieveDatetimeDatabaseFormat(value);
                communicator.addParameter(field, value);
                if(validate) fieldAssigned = true;
            }else globalValidationFailed.push(feedback);
        }
    }
    
    return fieldAssigned;
}